/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.jtalker.client.plugins.TicTacToe;

import java.lang.reflect.Method;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import com.jtalker.client.JTalkerClientCommandInterface;
import com.jtalker.client.JTalkerClientPlugInInterface;
import com.jtalker.client.JTalkerClientPluginConnector;

/**
 * 
 * @author christoph
 */
public class TicTacToe implements JTalkerClientPlugInInterface, JTalkerClientCommandInterface {

	private static int ENEMY_REMOTE = 0;
	// private static int ENEMY_AI = 1;
	private boolean gameIsActive = false;
	private ImageIcon myIcon = null;

	public int winCounterUser = 0;
	public int winCounterEnemy = 0;

	// The parent translator object 插件与主窗口的通信都依赖于此对象.
	private JTalkerClientPluginConnector myParentObject = null;
	/** 游戏面板. */
	private TTTWindow myTttWindow;
	/** 游戏设置. */
	private TTTSettings myTttSettings;

	public String myName = "";
	public String enemyName = "";

	public TicTacToe() {
		this.myTttWindow = new TTTWindow(this);
		this.myTttSettings = new TTTSettings(this);
		this.myIcon = new ImageIcon(getClass().getResource("ttticon.png"));
	}

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String[] args) {
		// Main method for debuggig only!
		new TicTacToe().getMainFrame().setVisible(true);
	}

	public JFrame getMainFrame() {
		if (this.myParentObject != null) {
			this.myTttSettings.setUserList(this.myParentObject.getOnlineUsers());
		}

		if (!this.gameIsActive) {
			return this.myTttSettings;
		} else {
			return this.myTttWindow;
		}
	}

	public JFrame getSettingsFrame() {
		if (this.myParentObject != null) {
			this.myTttSettings.setUserList(this.myParentObject.getOnlineUsers());
		}

		return this.myTttSettings;
	}

	public ImageIcon getIcon() {
		return this.myIcon;
	}

	public String getName() {
		return "Tic-Tac-Toe";
	}

	public String getDescription() {
		return "The player who succeeds in placing three respective marks in a horizontal, vertical or diagonal row wins the game.";
	}

	public boolean setParentObject(JTalkerClientPluginConnector connector) {
		this.myParentObject = connector;
		this.myParentObject.registerForCommandResponse(this);
		this.myName = this.myParentObject.getUserName();
		System.out.println("+ (TicTacToe) Ok, parent object initialized: " + connector);
		return true;
	}

	public void unload() {
		this.myParentObject.deRegisterForCommandResponse(this);
		this.myParentObject = null;
	}

	public Method[] getCommandMethods() {
		Method[] myMethods = new Method[4];

		try {
			myMethods[0] = this.getClass().getDeclaredMethod("inviteForGame", new Class[] { String.class });
			myMethods[1] = this.getClass().getDeclaredMethod("turn", new Class[] { String.class });
			myMethods[2] = this.getClass().getDeclaredMethod("restartGame");
			myMethods[3] = this.getClass().getDeclaredMethod("cancelRunningGame");
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

		return myMethods;
	}

	// ////////////////// Command Methods ////////////////////

	/** Invite for a game */
	public String inviteForGame(String userName) {
		System.out.println("----> inviteForGame()");

		if (this.gameIsActive) {
			return "NOTOK: Another Game is running";
		}
		this.winCounterUser = 0;
		this.winCounterEnemy = 0;

		int retVal = JOptionPane.showConfirmDialog(null, "The user " + userName
				+ " wants to play\nTic-Tac-Toe with you.\nDo you agree?", "Want to play?", JOptionPane.YES_NO_OPTION);

		if (retVal == JOptionPane.YES_OPTION) {
			this.enemyName = userName;
			this.myTttWindow.startNewGame(false, 2, ENEMY_REMOTE, -1, this.enemyName);
			this.myTttWindow.setVisible(true);
			this.gameIsActive = true;
			return "OK";
		} else {
			return "NOTOK: Rejected";
		}
	}

	/** Receives a turn from remote user */
	public String turn(String index) {
		System.out.println("----> turn()");

		if (!this.gameIsActive) {
			return "NOTOK: Invite first";
		}
		if (this.myTttWindow.setExternalAction(Integer.parseInt(index))) {
			return "OK";
		} else {
			return "NOTOK: Unknown error occured";
		}
	}

	/** Restarts the game with the current enemy and settings */
	public String restartGame() {
		System.out.println("----> restartGame()");

		this.myTttWindow.startNewGame(false, 1, ENEMY_REMOTE, -1, this.enemyName);
		this.myTttWindow.setVisible(true);
		this.gameIsActive = true;

		return "OK";
	}

	/** Stops a running game */
	public String cancelRunningGame() {
		System.out.println("----> cancelRunningGame()");

		this.gameIsActive = false;
		this.myTttWindow.setVisible(false);
		return "OK";
	}

	// ////////////////////////////////////////////////////////////

	public Method[] getUserMethods() {
		return null;
	}

	public boolean setCommandAnswer(String id, String from, String content) {
		if (id.equals("msgTTTInvite")) {
			if (content.equals("OK")) {
				if (this.gameIsActive) {
					return false;
				}

				System.out.println("----> Got OK for INVITE");
				this.winCounterUser = 0;
				this.winCounterEnemy = 0;

				this.myTttWindow.setVisible(true);

				this.myTttWindow.startNewGame(true, 1, this.myTttSettings.getGameType(),
						this.myTttSettings.getSelectedAI(), this.myTttSettings.getSelectedUser());

				this.gameIsActive = true;
				return true;

			} else {
				System.out.println("----> *** Got NOTOK for invite.");
				JOptionPane.showMessageDialog(this.myTttWindow, "Can't start a game.\nThe message was:\n" + content,
						"Can't start a game.", JOptionPane.INFORMATION_MESSAGE);
			}

			return false;
		}

		if (id.equals("msgTTTRestart")) {
			if (content.equals("OK")) {
				if (this.gameIsActive) {
					return false;
				}

				System.out.println("----> Got OK for RESTART");

				this.myTttWindow.setVisible(true);

				this.myTttWindow.startNewGame(true, 1, this.myTttSettings.getGameType(),
						this.myTttSettings.getSelectedAI(), this.myTttSettings.getSelectedUser());

				this.gameIsActive = true;
				return true;

			} else {
				System.out.println("----> *** Got NOTOK for invite.");
				JOptionPane.showMessageDialog(this.myTttWindow, "Can't restart a game.\nThe message was:\n" + content,
						"Can't start a game.", JOptionPane.INFORMATION_MESSAGE);
			}

			return false;
		}

		if (id.equals("msgTTTCancel")) {
			if (content.equals("OK")) {
				System.out.println("----> Got OK for CANCEL - cancel too.");
				this.gameIsActive = false;
				this.myTttWindow.setVisible(false);
			}
		}

		return false;
	}

	/** Will be called from the settings menu */
	public void startNewGame(boolean reStart) {
		if (reStart && this.myName.length() > 0 && this.enemyName.length() > 0) {
			System.out.println("----> Restarting the game with the same settings");
			this.gameIsActive = false;
			this.myParentObject.sendMessage("jtplugin.TicTacToe::restartGame()", this.enemyName, "command", "",
					"msgTTTRestart");

			return;
		}

		if (this.myTttSettings.getGameType() == ENEMY_REMOTE) {
			// Remote Game
			this.enemyName = this.myTttSettings.getSelectedUser();
			this.gameIsActive = false;
			this.myParentObject.sendMessage("jtplugin.TicTacToe::inviteForGame(" + this.myName + ")", this.enemyName,
					"command", "", "msgTTTInvite");
		} else {
			// Local Game
			this.myTttWindow.startNewGame(true, 1, this.myTttSettings.getGameType(),
					this.myTttSettings.getSelectedAI(), "AI");

			this.enemyName = "AI";
			this.myTttWindow.setVisible(true);
			this.gameIsActive = true;
		}
	}

	/** Will be called from the gema window */
	public void endCurrentGame() {
		if (this.myTttSettings.getGameType() == ENEMY_REMOTE) {
			// Remote Game
			this.myParentObject.sendMessage("jtplugin.TicTacToe::cancelRunningGame()", this.enemyName, "command", "",
					"msgTTTCancel");

			this.gameIsActive = false;
		} else {
			// Local Game
			this.myTttWindow.startNewGame(true, 1, this.myTttSettings.getGameType(),
					this.myTttSettings.getSelectedAI(), "AI");

			this.myTttWindow.setVisible(false);
			this.gameIsActive = false;
		}
	}

	public void setTurn(int field) {
		if (this.myTttSettings.getGameType() == ENEMY_REMOTE) {
			// Remote Game
			this.myParentObject.sendMessage("jtplugin.TicTacToe::turn(" + field + ")", this.enemyName, "command", "",
					"msgTTTTurn");
		}
	}
}
